﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using OpenAPI.Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace OpenAPI.Filter
{
    public class GlobalAuthorzationAttribute : IAuthorizationFilter
    {
        public void OnAuthorization(AuthorizationFilterContext context)
        {

            //解析url
            //// {/ Home / Index}
            //var url = context.HttpContext.Request.Path.Value;
            //if (string.IsNullOrWhiteSpace(url))
            //{
            //    return;
            //}

            //var list = url.Split("/");
            //if (list.Length <= 0 || url == "/")
            //{
            //    return;
            //}
            //var controllerName = list[1].ToString().Trim();
            //var actionName = list[2].ToString().Trim();


            if (HasAllowAnonymous(context))
                return;


            //string host=context.HttpContext.Request.Host.Value;

            //if (host.Contains("127.0.0.1")||host.Contains("localhost"))
            //{
            //    return;
            //}




            StringValues appKey;

            if (!context.HttpContext.Request.Headers.TryGetValue("appKey", out appKey))
            {
                context.Result = new ContentResult() { Content = "报文头中的appKey为空", StatusCode = 200 };
                return;
            }


            //伪代码
            //根据appKey,获取AppInfo信息

            //一、数据库设计：
            //T_AppInfos（App 表）：
            //字段名 类型 是否允许为空
            //Id bigint NO
            //Name nvarchar(100) NO
            //AppKey nvarchar(100) NO
            //AppSecret nvarchar(100) NO
            //CreateDateTime datetime NO
            //IsEnabled bool NO

            //判断是否存在,不存在的AppKey

            //判断是否禁用,AppKey已经被封禁


            //通过appid获取appSecret逻辑
            string appSecret = "fsdfsdf3435234";

            StringValues sign;

            if (!context.HttpContext.Request.Headers.TryGetValue("sign", out sign))
            {
                context.Result = new ContentResult() { Content = "报文头中的sign为空", StatusCode = 200 };
                return;
            }

            string qs = "";

            var aaa = context.HttpContext.Request;


            if (context.HttpContext.Request.Method == "GET")
            {
                var o = context.HttpContext.Request.Query.AsEnumerable().OrderBy(kv => kv.Key).Select(kv => kv.Key + "=" + kv.Value);

                qs = string.Join("&", o);
            }
            else if (context.HttpContext.Request.Method == "POST")
            {
                var o = context.HttpContext.Request.Form.AsEnumerable().OrderBy(kv => kv.Key).Select(kv => kv.Key + "=" + kv.Value);

                qs = string.Join("&", o);
            }
            else
            {
                context.Result = new ContentResult() { Content = "无效的请求方法", StatusCode = 200 };
                return;
            }


            string computedSign = EncryptExtension.MD5Hash(qs + appSecret);

            if (!sign.ToString().Equals(computedSign, StringComparison.CurrentCultureIgnoreCase))
            {
                context.Result = new ContentResult() { Content = "sign验证失败", StatusCode = 200 };
                return;
            }


            return;

        }


        private bool HasAllowAnonymous(AuthorizationFilterContext context)
        {
            var filters = context.Filters;
            for (var i = 0; i < filters.Count; i++)
            {
                if (filters[i] is IAllowAnonymousFilter)
                {
                    return true;
                }
            }

            // When doing endpoint routing, MVC does not add AllowAnonymousFilters for AllowAnonymousAttributes that
            // were discovered on controllers and actions. To maintain compat with 2.x,
            // we'll check for the presence of IAllowAnonymous in endpoint metadata.
            var endpoint = context.HttpContext.GetEndpoint();
            if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
            {
                return true;
            }

            return false;
        }



    }
}
